using System;
using System.Collections.Generic;
using System.Text;

namespace RapidHDL
{    
    public class HardwareScripts
    {
        Dictionary<string, HardwareScript> dicHardwareScripts;
        Dictionary<int, string> dicScriptIndex;

        int iCurrentIndex=0;
        bool bCompleted = false;
        string sTranscript = "";
        string sFullTranscript = "";

        RapidHardware oRapidHardware;

        public HardwareScripts(RapidHardware poRapidHardware)
        {
            oRapidHardware = poRapidHardware;
            dicHardwareScripts = new Dictionary<string, HardwareScript>();
            dicScriptIndex = new Dictionary<int, string>();
        }

        public HardwareScript NewScript(string psName)
        {
            if (dicHardwareScripts.ContainsKey(psName))
                return dicHardwareScripts[psName];
            HardwareScript oHardwareScript = new HardwareScript(oRapidHardware, psName);
            RegisterScript(psName, oHardwareScript);
            return oHardwareScript;
        }

        public HardwareScript this[string psName]
        {
            get
            {
                if (dicHardwareScripts.ContainsKey(psName))
                    return dicHardwareScripts[psName];
                throw new Exception(psName + " does not exist as a hardware script");
            }
        }

        public HardwareScript this[int piIndex]
        {
            get
            {
                if (dicScriptIndex.ContainsKey(piIndex))
                    return dicHardwareScripts[dicScriptIndex[piIndex]];
                throw new Exception("Index " + piIndex.ToString() + " does not exist as a hardware script");
            }
        }

        private void RegisterScript(string psName, HardwareScript poHardwareScript)
        {
            dicHardwareScripts.Add(psName, poHardwareScript);
            dicScriptIndex.Add(dicScriptIndex.Count, psName);
        }

        public bool Completed
        {
            get { return bCompleted; }
        }

        public string CurrentScriptName
        {
            get
            {
                if (bCompleted)
                    return "Completed";

                return this[iCurrentIndex].Name;
            }
        }

        public HardwareScript CurrentScript
        {
            get
            {
                if (iCurrentIndex >= dicHardwareScripts.Count)
                    return this[iCurrentIndex];
                return null;
            }
        }

        public string Transcript
        {
            get { return sTranscript; }
        }

        public bool DoScripts()
        {
            return DoScripts(false);
        }

        public bool DoScripts(bool pbResume)
        {
            return DoScripts(pbResume,false);
        }

        public bool DoScripts(bool pbResume, bool pbNoPause)
        {
            sTranscript = "";
            if (!pbResume || bCompleted)
            {
                iCurrentIndex = 0;
                bCompleted = false;
                sFullTranscript = "";
            }

            while (iCurrentIndex < dicHardwareScripts.Count)
            {
                HardwareScript oScript = this[iCurrentIndex];
                bool bResult = oScript.DoScript(pbResume, pbNoPause);
                sFullTranscript += oScript.Transcript;
                sTranscript = oScript.Transcript;
                if (!bResult)
                    return false;
                if (oScript.Completed)
                {
                    iCurrentIndex++;
                    if (iCurrentIndex >= dicHardwareScripts.Count)
                    {
                        bCompleted = true;
                        return true;
                    }
                }
                if (!pbNoPause)
                {
                    return true;
                }
            }
            return true;
        }

        public void WriteVerilogTestBenches()
        {
            int iIdx = 0;
            foreach (HardwareScript oScript in dicHardwareScripts.Values)
            {
                oScript.WriteVerilogTestBench(iIdx);
                oScript.WriteMachTA(iIdx);
                iIdx++;
            }
        }

        public string SimulateVerilogTestBenches()
        {
            int iIdx = 0;
            string sResult = "";
            foreach (HardwareScript oScript in dicHardwareScripts.Values)
            {
                sResult += oScript.SimulateVerilogTestBench(iIdx);
                iIdx++;
            }
            return sResult.Trim();
        }

        public string SimulateSynthesisVerilogTestBenches()
        {
            int iIdx = 0;
            string sResult = "";
            foreach (HardwareScript oScript in dicHardwareScripts.Values)
            {
                oScript.WriteSynthesisVerilogTestBench(iIdx);
                sResult += oScript.SimulateSynthesisVerilogTestBench(iIdx);
                iIdx++;
            }
            return sResult.Trim();
        }

    }
}
